package com.ruoyi.syf.handler.task.strategy;

import com.ruoyi.common.utils.CronUtil;
import com.ruoyi.common.utils.DateUtils;
import com.ruoyi.common.utils.MyCalendar;
import com.ruoyi.syf.common.constant.TaskType;
import com.ruoyi.syf.handler.task.TaskStrategy;
import com.ruoyi.syf.service.HolidayInfoService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.Date;

/**
 * 隐患排查定时任务策略-节假日
 *
 * @author yr
 * @date 2024-07-31
 */
@Service
public class HolidayTaskStrategy implements TaskStrategy {

    @Autowired
    private HolidayInfoService holidayInfoService;

    @Override
    public String getTaskType() {
        return TaskType.HOLIDAY;
    }

    @Override
    public String toCronExpression(int num, String timeUnit, Date startTime) throws IllegalAccessException {
        MyCalendar calendar = new MyCalendar(startTime);
        return CronUtil.toCronExpression(calendar,num,timeUnit,startTime);
    }

    @Override
    public Date getNextBeginTime(Date date, Date startTime, Integer cycle, String cycleUnit) throws IllegalAccessException {
        Date time = DateUtils.getNextDateByCycle(date, cycle, cycleUnit);
        boolean flag = holidayInfoService.ifHoliday(DateUtils.parseDate(DateUtils.dateTime(time)));
        if(!flag){
            if(DateUtils.getDaysBetween(time,date) == 0){
                time = DateUtils.addDay(time,1);
            }
            return getNextBeginTime(time,startTime,cycle,cycleUnit);
        }
        return time;
    }

    @Override
    public Date getLastBeginTime(Date startTime, Integer cycle, String cycleUnit) throws IllegalAccessException {
        Date time = DateUtils.getLastDateByCycle(startTime, cycle, cycleUnit);
        boolean flag = (boolean)holidayInfoService.ifHoliday(DateUtils.parseDate(DateUtils.dateTime(time)));
        if(!flag){
            if(DateUtils.getDaysBetween(time,startTime) == 0){
                time = DateUtils.addDay(time,-1);
            }
            return getLastBeginTime(time,cycle,cycleUnit);
        }
        return time;
    }

    @Override
    public Date getRecentBeginTime(Date startTime, Integer cycle, String cycleUnit) throws IllegalAccessException {
        return getTimeByCycle(startTime, cycle, cycleUnit, System.currentTimeMillis());
    }

    private Date getTimeByCycle(Date startTime, Integer cycle, String cycleUnit, long time) throws IllegalAccessException {
        Date dateByCycle = getNextBeginTime(startTime, null,cycle, cycleUnit);
        if (dateByCycle.getTime() <= time) {
            return getTimeByCycle(dateByCycle, cycle, cycleUnit, time);
        }
        return dateByCycle;
    }

}
